﻿using System;
using System.IO;
using System.Dynamic;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;

namespace Webview2async
{
    public class CoreWebView2Event
    {
        public CoreWebView2 CoreWebView2;
        public dynamic WebView2Environment;
        public CoreWebView2Event()
        {
   
        }

        public void SetData(dynamic View2, dynamic Environment)
        {
            CoreWebView2 = View2;
            WebView2Environment = Environment;
        }


        public delegate void StringType(string unid, string str);
        public delegate void StringTypeErr(string typeid, string unid, string str);
        public delegate void CooikesType(string unid, List<CoreWebView2Cookie> Cookies);

        public event StringType onCoreWebView2ExecuteScriptAsync;
        public event StringType onAddScriptToExecuteOnDocumentCreatedAsync;
        public event StringTypeErr onError;
        public event StringType onGetContent;

        public event CooikesType onCooikes;
        public event StringType onCallDevToolsProtocolMethodAsync;
        public event StringType onTrySuspendAsync;
        public string ContentRead(Stream txt)
        {
            string value = "";
            using (var reader = new StreamReader(txt))
            {
                value = reader.ReadToEnd();
            }
            return value;
        }

        public async Task GetContent(string unid, dynamic ResponseView)
        {
            try
            {
                Stream Content = await ResponseView.GetContentAsync();
                onGetContent(unid, ContentRead(Content));
            }
            catch (Exception e)
            {
                onError("GetContent", unid, e.Message);
            }
        }



        //CoreWebView2 异步方法
        public async Task Cookies(string unid, string url)
        {
            try
            {
                List<CoreWebView2Cookie> Cooikes = await CoreWebView2.CookieManager.GetCookiesAsync(url);
                onCooikes(unid, Cooikes);

            }
            catch (Exception e)
            {
                onError("AwaitCookies", unid + "|" + url, e.Message);

            }
        }


        public async Task CallDevToolsProtocolMethodAsync(string unid,string methodName, string parametersAsJson)
        {
            try
            {
                string ret = await CoreWebView2.CallDevToolsProtocolMethodAsync( methodName,  parametersAsJson);
                onCallDevToolsProtocolMethodAsync(unid, ret);

            }
            catch (Exception e)
            {
                onError("CallDevToolsProtocolMethodAsync", methodName , e.Message);

            }
        }

        public async Task CallDevToolsProtocolMethodAsync(string unid, string methodName, string parametersAsJson,dynamic callback)
        {
            try
            {
                callback( await CoreWebView2.CallDevToolsProtocolMethodAsync(methodName, parametersAsJson));
            }
            catch (Exception e)
            {
                onError("CallDevToolsProtocolMethodAsync", methodName, e.Message);

            }
        }



        public async Task AddScriptToExecuteOnDocumentCreatedAsync( string unid, string script)
        {
            try
            {
                string js = await CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script);
                onAddScriptToExecuteOnDocumentCreatedAsync(unid, js);
            }
            catch (Exception e)
            {
                onError("AddScriptToExecuteOnDocumentCreatedAsync", unid, e.Message);
            }
        }



        public async Task CoreWebView2ExecuteScriptAsync(string unid, string javaScript)
        {
            try
            {
                string js = await CoreWebView2.ExecuteScriptAsync(javaScript);
                onCoreWebView2ExecuteScriptAsync(unid, js);
            }
            catch (Exception e)
            {
                onError("CoreWebView2ExecuteScriptAsync", unid, e.Message);
            }
        }

        public async Task TrySuspendAsync( string unid)
        {
            try
            {
                await CoreWebView2.TrySuspendAsync();
                onTrySuspendAsync(unid, "ok");
            }
            catch (Exception e)
            {
                onError("TrySuspendAsync", unid, e.Message);
            }
        }

    }


    public class Webview2async
    {
        public WebView2 WebView2Control;
        public CoreWebView2Environment WebView2Environment;

        public delegate void StringType(string unid, string str);
        public delegate void StringTypeErr(string typeid, string unid, string str);
        public delegate void CoreWebViewType(string unid, CoreWebView2Controller CoreWebView2);
        public delegate void CoreWebViewAsyncType(string unid, CoreWebView2CompositionController CoreWebView2Composition);
        public delegate void CoreWebView2EnvironmentType(string unid, CoreWebView2Environment CoreWebView2Environmen);
       
        public event StringTypeErr onError;
        public event StringType onExecuteScriptAsync;

        public event CoreWebViewAsyncType onCreateCoreWebView2CompositionControllerAsync;
        public event CoreWebViewType onCreateCoreWebView2ControllerAsync;
        public event CoreWebView2EnvironmentType onEnsureCoreWebView2Async;

        public Webview2async()
        {
            //CoreWebView2CreationProperties CoreWebView2Creation = new CoreWebView2CreationProperties();
           // CoreWebView2Creation.UserDataFolder = UserDataFolder;
            WebView2Control = new WebView2();
        }
        public async Task EnsureCoreWebView2Async(string unid, string UserDataFolder, string env)
        {
            try
            {

                CoreWebView2EnvironmentOptions Options = new CoreWebView2EnvironmentOptions(env,null,null,false);
                WebView2Environment = await CoreWebView2Environment.CreateAsync(null, UserDataFolder, Options);
                await WebView2Control.EnsureCoreWebView2Async(WebView2Environment);
                onEnsureCoreWebView2Async(unid, WebView2Environment);
            } 
            catch (Exception e)
            {
                onError("EnsureCoreWebView2Async","", e.Message);
            }
        }

        public async Task ExecuteScriptAsync(string unid, string script)
        {
            try
            {
                string js = await WebView2Control.ExecuteScriptAsync(script);
                onExecuteScriptAsync(unid, js);
            }
            catch (Exception e)
            {
                onError("ExecuteScriptAsync", unid, e.Message);
            }
        }

        public async Task CreateCoreWebView2CompositionControllerAsync(string unid, int i)
        {
            try
            {
                IntPtr ParentWindow = new IntPtr(i);
                CoreWebView2CompositionController CoreWebView2Composition = await WebView2Environment.CreateCoreWebView2CompositionControllerAsync(ParentWindow);
                onCreateCoreWebView2CompositionControllerAsync(unid, CoreWebView2Composition);
            }
            catch (Exception e)
            {
                onError("CreateCoreWebView2CompositionControllerAsync", unid, e.Message);
            }
        }


        public async Task CreateCoreWebView2ControllerAsync(string unid, int i)
        {
            try {
                IntPtr ParentWindow = new IntPtr(i);
                CoreWebView2Controller CoreWebView2 = await WebView2Environment.CreateCoreWebView2ControllerAsync(ParentWindow);
                onCreateCoreWebView2ControllerAsync( unid, CoreWebView2);
            } catch (Exception e)
            {
                onError("CreateCoreWebView2ControllerAsync",  unid, e.Message);
            }
        }


     
    }
}
